package emulator.unittest.support;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;

import emulator.support.*;
import emulator.util.MemoryPtr;

public class OperandEvalTest {
	private byte[] memory;
	private CpuState cpu_state;

	@Before
	public void setUp() throws Exception {
		memory = new byte[65536];
		for (int i = 0; i < memory.length; i++)
			memory[i] = (byte)(i & 0xff);
		cpu_state = new CpuState();
		cpu_state.setValue("A", 10);
		cpu_state.setValue("X", 20);
		cpu_state.setValue("Y", 30);
		cpu_state.setValue("PC", 40);
		cpu_state.setValue("SP", 50);
		cpu_state.setValue("Flags", 0x60);
	}
	
	@Test
	public void testAbsoluteOperandGetDetails()
	{
		assertEquals("($0201) -> $01", new AbsoluteOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($0504) -> $04", new AbsoluteOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("($0100) -> $00", new AbsoluteOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}

	@Test
	public void testAbsoluteXOperandGetDetails()
	{
		assertEquals("($0201 + $14) -> $15", new AbsoluteXOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($0504 + $14) -> $18", new AbsoluteXOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("($0100 + $14) -> $14", new AbsoluteXOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}

	@Test
	public void testAbsoluteYOperandGetDetails()
	{
		assertEquals("($0201 + $1E) -> $1F", new AbsoluteYOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($0504 + $1E) -> $22", new AbsoluteYOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("($0100 + $1E) -> $1E", new AbsoluteYOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}
	
	@Test
	public void testDisplacementOperandGetDetails()
	{
		assertEquals("PC + $01 -> $0003", new DisplacementOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("PC + $81 -> $0003", new DisplacementOperandEval(new MemoryPtr(memory, 128)).getDetails(cpu_state));
		assertEquals("PC + $00 -> $0001", new DisplacementOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}
	
	@Test
	public void testImmediateAddressOperandGetDetails()
	{
		assertEquals("$0201", new ImmediateAddressOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("$0504", new ImmediateAddressOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("$0100", new ImmediateAddressOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}
	
	@Test
	public void testIndirectAddressOperandGetDetails()
	{
		assertEquals("($0201) -> $0201", new IndirectAddressOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($0504) -> $0504", new IndirectAddressOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("($0100) -> $0100", new IndirectAddressOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}
	
	@Test
	public void testIndirectXOperandGetDetails()
	{
		assertEquals("(($01 + $14 -> $15) -> $1615) -> $15", new IndirectXOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("(($04 + $14 -> $18) -> $1918) -> $18", new IndirectXOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("(($FF + $14 -> $13) -> $1413) -> $13", new IndirectXOperandEval(new MemoryPtr(memory, 65534)).getDetails(cpu_state));
	}
	
	@Test
	public void testIndirectYOperandGetDetails()
	{
		assertEquals("(($01) + Y -> $0201 + $1E -> $021F) -> $1F", new IndirectYOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("(($04) + Y -> $0504 + $1E -> $0522) -> $22", new IndirectYOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("(($00) + Y -> $0100 + $1E -> $011E) -> $1E", new IndirectYOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}

	@Test
	public void testZeroPageOperandGetDetails()
	{
		assertEquals("($01) -> $01", new ZeroPageOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($04) -> $04", new ZeroPageOperandEval(new MemoryPtr(memory, 3)).getDetails(cpu_state));
		assertEquals("($00) -> $00", new ZeroPageOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}

	@Test
	public void testZeroPageXOperandGetDetails()
	{
		assertEquals("($01 + $14) -> $15", new ZeroPageXOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($F4 + $14) -> $08", new ZeroPageXOperandEval(new MemoryPtr(memory, 243)).getDetails(cpu_state));
		assertEquals("($00 + $14) -> $14", new ZeroPageXOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}

	@Test
	public void testZeroPageYOperandGetDetails()
	{
		assertEquals("($01 + $1E) -> $1F", new ZeroPageYOperandEval(new MemoryPtr(memory, 0)).getDetails(cpu_state));
		assertEquals("($F4 + $1E) -> $12", new ZeroPageYOperandEval(new MemoryPtr(memory, 243)).getDetails(cpu_state));
		assertEquals("($00 + $1E) -> $1E", new ZeroPageYOperandEval(new MemoryPtr(memory, 65535)).getDetails(cpu_state));
	}
	
}
